package com.bci.pwtz.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.bci.pwtz.common.util.PaginationList;
import com.bci.pwtz.exception.PwtzDatabaseException;
import com.bci.pwtz.mysql.dao.CompanyActionMapper;
import com.bci.pwtz.mysql.dao.CompanyMapper;
import com.bci.pwtz.mysql.dao.CompanyRoleActionMapper;
import com.bci.pwtz.mysql.dao.CompanyRoleMapper;
import com.bci.pwtz.mysql.dao.CompanyUserRoleMapper;
import com.bci.pwtz.mysql.model.Company;
import com.bci.pwtz.mysql.model.CompanyAction;
import com.bci.pwtz.mysql.model.CompanyRole;
import com.bci.pwtz.mysql.model.CompanyRoleAction;
import com.bci.pwtz.service.CompanyRoleService;

/**
 * 一句话描述 <br/>
 * <p>
 * Description:<br/>
 * <p>
 * TODO 详细描述
 * 
 * <p>
 * For Examples <br/>
 * 
 * <PRE>
 *      TODO 代码使用示例
 * </PRE>
 * <p>
 */
@Service
public class CompanyRoleServiceImpl implements CompanyRoleService
{

    private CompanyRoleMapper companyRoleMapper;
    
    private CompanyRoleActionMapper companyRoleActionMapper;
    
    private CompanyMapper companyMapper;
    
    private CompanyActionMapper companyActionMapper;
    
    private CompanyUserRoleMapper companyUserRoleMapper;
    
    private JdbcTemplate jdbcTemplate;
    
    /**
     * @return the companyRoleMapper
     */
    public CompanyRoleMapper getCompanyRoleMapper()
    {
        return companyRoleMapper;
    }

    /**
     * @param companyRoleMapper the companyRoleMapper to set
     */
    public void setCompanyRoleMapper(CompanyRoleMapper companyRoleMapper)
    {
        this.companyRoleMapper = companyRoleMapper;
    }

    /**
     * @return the companyRoleActionMapper
     */
    public CompanyRoleActionMapper getCompanyRoleActionMapper()
    {
        return companyRoleActionMapper;
    }

    /**
     * @param companyRoleActionMapper the companyRoleActionMapper to set
     */
    public void setCompanyRoleActionMapper(CompanyRoleActionMapper companyRoleActionMapper)
    {
        this.companyRoleActionMapper = companyRoleActionMapper;
    }
    
    public CompanyMapper getCompanyMapper()
    {
        return companyMapper;
    }

    public void setCompanyMapper(CompanyMapper companyMapper)
    {
        this.companyMapper = companyMapper;
    }
    
    public CompanyActionMapper getCompanyActionMapper()
    {
        return companyActionMapper;
    }

    public void setCompanyActionMapper(CompanyActionMapper companyActionMapper)
    {
        this.companyActionMapper = companyActionMapper;
    }
    
    public CompanyUserRoleMapper getCompanyUserRoleMapper()
    {
        return companyUserRoleMapper;
    }

    public void setCompanyUserRoleMapper(CompanyUserRoleMapper companyUserRoleMapper)
    {
        this.companyUserRoleMapper = companyUserRoleMapper;
    }

    private static final Logger _logger = Logger.getLogger(CompanyRoleServiceImpl.class);
    
    public int add(CompanyRole companyRole) throws PwtzDatabaseException
    {
        int result=0;
        if (_logger.isDebugEnabled())
        {
            _logger.debug("add:companyRole=" + companyRole.toString());
        }
        if (companyRole == null)
        {
            if (_logger.isDebugEnabled())
            {
                _logger.debug("add,companyRole is null");
            }
            return 0;
        }
        try
        {
            result = companyRoleMapper.insertSelective(companyRole);
        }
        catch (DataAccessException _e)
        {
            _logger.error(ExceptionUtils.getStackTrace(_e));
            throw new PwtzDatabaseException();
        }
        return result;
    }

    public List<CompanyRole> findCompanyRoleByUserId(Long userId) throws PwtzDatabaseException
    {
        
        if (_logger.isInfoEnabled())
        {
            _logger.info("findCompanyRoleByUserId:|userId=" + userId);
        }

        List<CompanyRole> list = null;
        try
        {
                list = companyRoleMapper.findRoleByUserId(userId);
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }
    
    public List<CompanyRoleAction> selectByRoleId(Long roleId) throws PwtzDatabaseException
    {
        
        if (_logger.isInfoEnabled())
        {
            _logger.info("selectByRoleId:|roleId=" + roleId);
        }

        List<CompanyRoleAction> list = null;
        try
        {
                list = companyRoleActionMapper.selectByRoleId(roleId);
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }

    @Override
    public PaginationList<CompanyRole> selectByCompanyIds(Long[] companyIds,int pageIndex,int pageSize) throws PwtzDatabaseException
    {
        if(_logger.isInfoEnabled())
        {
            _logger.info("selectByCompanyIds method invoke");
        }
        PaginationList<CompanyRole> paginationList = new PaginationList<CompanyRole>();
        List<CompanyRole> list=null;
        int totalCount = 0;
        int totalPage = 0;
        int beginIndex=pageSize*pageIndex-pageSize;
        
        try
        {
                list = companyRoleMapper.selectByCompanyIds(companyIds,beginIndex,pageSize);
                totalCount = companyRoleMapper.selectByCompanyIdsNum(companyIds);
                
                if(pageSize!=0)
                {
                    totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;                   
                }
                else
                {
                    pageIndex=1;
                    if(list!=null && list.size()>0)
                    {
                        totalCount = list.size();
                    }
                }               
                paginationList.setTotalPage(totalPage);
                paginationList.setCurrPage(pageIndex);
                paginationList.setPageSize(pageSize);
                paginationList.setRecords(list);
                paginationList.setTotalRecord(totalCount);
                return paginationList;                
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }

    @Override
    public Set<String> getUserActionCodes(long companyUserId, long companyId) throws PwtzDatabaseException
    {
        Set<String> retVal = new HashSet<String>();
        String companyIds = companyId + "";
        try
        {
            Company company = companyMapper.selectByPrimaryKey(companyId);
            if (company == null)
                return null;
            long pid = company.getpId();
            while (true)
            {
                company = companyMapper.selectByPrimaryKey(pid);
                if (company == null || company.getpId() == 0)
                    break;
                pid = company.getpId();
                companyIds += "," + pid;
            }

            final String sql = "SELECT ACTION_CODE FROM T_COMPANY_USER_ROLE a JOIN T_COMPANY_ROLE_ACTION b ON b.COMPANY_ROLE_ID=a.COMPANY_ROLE_ID JOIN T_USER_COMPANY_REF c ON a.COMPANY_USER_ID = c.COMPANY_USER_ID WHERE a.COMPANY_USER_ID=? AND c.COMPANY_ID IN(" + companyIds + ")";
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql, companyUserId);
            for (Map<String, Object> m : list)
            {
                retVal.add(m.get("ACTION_CODE").toString());
            }
            return retVal;
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }

    @Override
    public boolean checkIsCreator(long companyUserId, long companyId) throws PwtzDatabaseException
    {        
        try
        {
            Company company = companyMapper.selectByPrimaryKey(companyId);
            if(company == null)
                return false;
            if(company.getCreatorId() == companyUserId)
                return true;
            long pid = company.getpId();
            while(true)
            {
                company = companyMapper.selectByPrimaryKey(pid);
                if(company == null||company.getpId() == 0)
                    break;
                if(company.getCreatorId() == companyUserId)
                    return true;
                pid = company.getpId();
            }
            return false;               
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }

    

    @Override
    public boolean checkHasAction(HttpServletRequest  request,String actionCode)
    {        
//        if(true)
//            return true;
        HttpServletRequest req = (HttpServletRequest)request;
//        boolean isSuper = Boolean.parseBoolean(req.getSession().getAttribute("isSuper")+"");
//        if(isSuper)
//            return true;
        
        //Set<String> actionCodes = (Set<String>)req.getSession().getAttribute("actionCodes");
        List<String> actionCodes = (List<String>)req.getSession().getAttribute("actionList");
        boolean enable =  Boolean.parseBoolean(req.getSession().getAttribute("companyEnable")+"");
        //CompanyUser companyUser = (CompanyUser)req.getSession().getAttribute("user");
        //Company company =  companyMapper.selectByPrimaryKey(companyUser.getLastCompanyId());
        if(!enable&&actionCode!=null)//(company.getStatus() == 2)
        {
            if(actionCode.indexOf("manage")!=-1||actionCode.indexOf("add")!=-1||actionCode.indexOf("edit")!=-1||actionCode.indexOf("delete")!=-1)
            {
                return false;
            }
        }
        if(actionCodes!= null && actionCodes.contains(actionCode))
            return true;
        return false;
    }
    @Override
    public boolean checkHasActions(HttpServletRequest  request,String actionCodes)
    {
        /*if(true)
            return true;*/
        if(StringUtils.isBlank(actionCodes))
            return true;
        String[] actionCodesArray = actionCodes.split(",");
        HttpServletRequest req = (HttpServletRequest)request;
        boolean isSuper = Boolean.parseBoolean(req.getSession().getAttribute("isSuper")+"");
        Set<String> currentActionCodes = (Set<String>)req.getSession().getAttribute("actionCodes");
        if(isSuper)
            return true;
        for(String a : actionCodesArray)
        {
            if(currentActionCodes.contains(a))
                return true;
        }
        return false;
    }

    public JdbcTemplate getJdbcTemplate()
    {
        return jdbcTemplate;
    }

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
    {
        this.jdbcTemplate = jdbcTemplate;
    }    
    
    @Override
    public CompanyRole selectDefault(Long companyId) throws PwtzDatabaseException
    {
        
        if (_logger.isInfoEnabled())
        {
            _logger.info("selectDefault:|companyId=" + companyId);
        }

        CompanyRole role = null;
        try
        {
            role = companyRoleMapper.selectDefault(companyId);
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return role;
    }
    
    @Override
    public List<CompanyAction> selectCompanyAction() throws PwtzDatabaseException
    {
        List<CompanyAction> list = null;
        try
        {
        	 	list = companyActionMapper.selectCompanyAction();
        }
        catch (DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }
    
    @Override
    public int addCompanyRole(String rolename, long companyId, long companyRoleId, String jurisdiction) throws PwtzDatabaseException
    {
        int result=0;
        String[] str = jurisdiction.split(",");
        try
        {
        	if(companyRoleId == 0){
        		CompanyRole companyRole = new CompanyRole();
        		companyRole.setRoleName(rolename);
        		companyRole.setCompanyId(companyId);
        		companyRole.setIsSuper(0);
        		result = companyRoleMapper.insertSelective(companyRole);
        		if(result > 0){
        			//System.out.println("companyRole.getCompanyRoleId()="+companyRole.getCompanyRoleId());
        			long roleId = companyRole.getCompanyRoleId();
        			for(int i=0;i<str.length;i++){
        				CompanyRoleAction companyRoleAction = new CompanyRoleAction();
        				companyRoleAction.setCompanyRoleId(roleId);
        				companyRoleAction.setActionCode(str[i]);
        				result = companyRoleActionMapper.insertSelective(companyRoleAction);
        			}
        		}
        	}else{
        		result = companyRoleActionMapper.deleteByCompanyRoleId(companyRoleId);
        		if(result > 0){
        			CompanyRole companyRole = new CompanyRole();
        			companyRole.setCompanyRoleId(companyRoleId);
            		companyRole.setRoleName(rolename);
            		result = companyRoleMapper.updateByPrimaryKeySelective(companyRole);
            		if(result > 0){
	        			for(int i=0;i<str.length;i++){
	        				CompanyRoleAction companyRoleAction = new CompanyRoleAction();
	        				companyRoleAction.setCompanyRoleId(companyRoleId);
	        				companyRoleAction.setActionCode(str[i]);
	        				result = companyRoleActionMapper.insertSelective(companyRoleAction);
	        			}
            		}
        		}
        	}
        }
        catch (DataAccessException _e)
        {
            _logger.error(ExceptionUtils.getStackTrace(_e));
            throw new PwtzDatabaseException();
        }
        return result;
    }
    
    @Override
    public int delCompanyRole(long companyRoleId) throws PwtzDatabaseException
    {
        int result = 0;
        try
        {
        	result = companyUserRoleMapper.selectCountByCompanyRoleId(companyRoleId);
        	if(result == 0){
        		result = companyRoleActionMapper.deleteByCompanyRoleId(companyRoleId);
    			if(result > 0){
    				result = companyRoleMapper.deleteByPrimaryKey(companyRoleId);
    			}
        	}else{
        		result = -1;
        	}
        }
        catch (DataAccessException _e)
        {
            _logger.error(ExceptionUtils.getStackTrace(_e));
            throw new PwtzDatabaseException();
        }
        return result;
    }
    
    @Override
    public boolean checkExistsCompanyRole(long companyId,long roleId) throws PwtzDatabaseException
    {       
        final String sql = "SELECT 1 FROM T_COMPANY_ROLE WHERE COMPANY_ID=? AND COMPANY_ROLE_ID=?";
        try
        {
        List<Map<String,Object>> objInfos = jdbcTemplate.queryForList(sql,companyId,roleId);
        if(objInfos.size()!=0)
            return true;
        else
            return false;
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }
    
    @Override
    public boolean checkExistsCompanyUserRole(long userid,long roleId) throws PwtzDatabaseException
    {       
        String sql = "SELECT 1 FROM T_COMPANY_USER_ROLE WHERE COMPANY_USER_ID=? AND COMPANY_ROLE_ID=?";
        try
        {
        List<Map<String,Object>> objInfos = jdbcTemplate.queryForList(sql,userid,roleId);
        if(objInfos.size()!=0)
            return true;
        else
            return false;
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }
    
    @Override
    public long selectCompanyRoleId(long companyId) throws PwtzDatabaseException
    {
    	String sql = "SELECT COMPANY_ROLE_ID FROM T_COMPANY_ROLE WHERE COMPANY_ID=? AND IS_SUPER=0 AND CAN_DELETE=2";
    	long ref = 0;
    	try
        {
	        List<Map<String,Object>> objInfos = jdbcTemplate.queryForList(sql,companyId);
	        if(objInfos.size()!=0){
	        	ref = (Long)objInfos.get(0).get("COMPANY_ROLE_ID");
	        	System.out.println(ref);
	        }   
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    	return ref;
    }
    
    @Override
    public boolean checkExistsUserCompanyRef(long userid,long companyId) throws PwtzDatabaseException
    {       
        String sql = "SELECT 1 FROM T_USER_COMPANY_REF WHERE COMPANY_USER_ID=? AND COMPANY_ID=?";
        try
        {
        List<Map<String,Object>> objInfos = jdbcTemplate.queryForList(sql,userid,companyId);
        if(objInfos.size()!=0)
            return true;
        else
            return false;
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }
    
    @Override
    public boolean checkExistsCompanyRoleAction(long companyRoleId,String actionCode) throws PwtzDatabaseException
    {       
        String sql = "SELECT 1 FROM T_COMPANY_ROLE_ACTION WHERE COMPANY_ROLE_ID=? AND ACTION_CODE=?";
        try
        {
        List<Map<String,Object>> objInfos = jdbcTemplate.queryForList(sql,companyRoleId,actionCode);
        if(objInfos.size()!=0)
            return true;
        else
            return false;
        }
        catch(DataAccessException e)
        {
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
    }

    @Override
    public List<CompanyRole> selectRole(long companyid, String rolename) throws PwtzDatabaseException
    {
        if(_logger.isDebugEnabled()){
            _logger.debug("selectRole: companyid="+companyid+"rolename="+rolename);
        }
        List<CompanyRole> list=null;
        try{
            list=companyRoleMapper.selectRole(companyid, rolename);
        }catch (DataAccessException e){
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }

    @Override
    public List<String> selectRoleAction(Long companyId, Long userId) throws PwtzDatabaseException
    {
        if(_logger.isDebugEnabled()){
            _logger.debug("selectRoleAction: companyId="+companyId+"userId="+userId);
        }
        List<String> list=null;
        try{
            list=companyRoleMapper.selectRoleAction(companyId, userId);
        }catch (DataAccessException e){
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }

    @Override
    public List<CompanyRole> selectCurrentRole(Long companyId, Long userId) throws PwtzDatabaseException
    {
        if(_logger.isDebugEnabled()){
            _logger.debug("selectCurrentRole: companyId="+companyId+"userId="+userId);
        }
        List<CompanyRole> list=null;
        try{
            list=companyRoleMapper.selectCurrentRole(companyId, userId);
        }catch (DataAccessException e){
            _logger.error(ExceptionUtils.getStackTrace(e));
            throw new PwtzDatabaseException();
        }
        return list;
    }
}
